/////////////////////////////////////////////////////////////////////////////
// Name:        ax_menu_toggle.cpp
// Purpose:     Toggle menu classes
// Author:      Julian Smart
// Modified by:
// Created:     2009-03-20
// RCS-ID:
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#include "wx/wx.h"
#include "wx/filename.h"

#include "ax/ax_menu_toggle.h"
#include "ax/ax_speech.h"

/*
 * AxToggleMenuItem implementation.
 */

IMPLEMENT_DYNAMIC_CLASS( AxToggleMenuItem, AxMenuItem )

AxToggleMenuItem::AxToggleMenuItem(const wxString& uncheckedLabel,
                                   const wxString& checkedLabel,
                                   const wxString& description,
                                   const wxString& id, bool checked):
    AxMenuItem(uncheckedLabel, description, id, NULL)
{
    SetKind(_("toggle"));
    SetUncheckedLabel(uncheckedLabel);
    SetCheckedLabel(checkedLabel);

    m_checked = checked;

    UpdateToggleLabel();

    SetActivator(new AxToggleActivator);
}

void AxToggleMenuItem::UpdateToggleLabel()
{
    if (IsChecked())
        SetLabel(GetCheckedLabel());
    else
        SetLabel(GetUncheckedLabel());
}

bool AxToggleMenuItem::Check(bool checked)
{
    m_checked = checked;
    UpdateToggleLabel();

    return true;
}

void AxToggleMenuItem::SendToggleUpdate(bool value)
{
    wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, AxGetId(GetId()));
    event.SetEventObject(this);
    event.SetInt(value ? 1 : 0);

    ProcessEvent(event);
}

/*
 * AxToggleActivator implementation.
 * Sets the value of a boolean variable when toggled.
 */

IMPLEMENT_DYNAMIC_CLASS( AxToggleActivator, AxActivator )

void AxToggleActivator::Copy(const AxToggleActivator& activator)
{
    AxActivator::Copy(activator);
}

AxToggleMenuItem* AxToggleActivator::GetToggleMenuItem() const
{
    return wxDynamicCast(GetMenuItem(), AxToggleMenuItem);
}

// Called just before the menu item is displayed.
bool AxToggleActivator::BeforeDisplay(AxMenuController* WXUNUSED(controller), AxMenuItem* WXUNUSED(item))
{
    UpdateUI(NULL, NULL);

    return true;
}

// Called during display, at intervals.
bool AxToggleActivator::UpdateUI(AxMenuController* WXUNUSED(controller), AxMenuItem* WXUNUSED(item))
{
    AxToggleMenuItem* toggleItem = GetToggleMenuItem();
    if (toggleItem)
    {
        toggleItem->TransferDataToMenu();
        toggleItem->UpdateToggleLabel();
    }

    return true;
}

AxMenu* AxToggleActivator::Activate(AxMenuController* controller, AxMenuItem* item)
{
    AxToggleMenuItem* toggleItem = GetToggleMenuItem();
    if (toggleItem)
    {
        toggleItem->Check(!toggleItem->IsChecked());
        toggleItem->TransferDataFromMenu();

        if (controller && item)
            controller->UpdateMenuItem(item);

        // Override previous emission, with up-to-date item
        controller->EmitSpeech(AxSpeechEventActivateItem, AxNavigationHintNone, AxSpeechFlagsPurge);

        toggleItem->SendToggleUpdate(toggleItem->IsChecked());
    }

    return NULL;
}

IMPLEMENT_DYNAMIC_CLASS( AxToggleValidator, AxValidator )

// Override to pass a value from the UI to a data structure
bool AxToggleValidator::TransferDataFromMenu()
{
    AxToggleMenuItem* toggleItem = wxDynamicCast(GetMenuItem(), AxToggleMenuItem);
    if (toggleItem)
    {
        if (m_boolPtr)
            * m_boolPtr = toggleItem->IsChecked();
    }

    return true;
}

// Override to pass a value from a data structure to the UI
bool AxToggleValidator::TransferDataToMenu()
{
    AxToggleMenuItem* toggleItem = wxDynamicCast(GetMenuItem(), AxToggleMenuItem);
    if (toggleItem)
    {
        if (m_boolPtr)
            toggleItem->Check(* m_boolPtr);
    }

    return true;
}

